package com.wisdytech.linkdcs.equipment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageInfo;
import com.wisdytech.common.bean.Filter;
import com.wisdytech.common.bean.StandardResult;
import com.wisdytech.common.constants.CommonConstants;
import com.wisdytech.common.exception.ServiceException;
import com.wisdytech.common.handler.BaseService;
import com.wisdytech.common.utils.BaseUtil;
import com.wisdytech.linkdcs.equipment.dao.IEqAlarmRecordDao;
import com.wisdytech.linkdcs.equipment.dao.IEqEquipAlarmParamDao;
import com.wisdytech.linkdcs.equipment.dto.ParamAlarmDefinition;
import com.wisdytech.linkdcs.equipment.model.AlarmRecord;
import com.wisdytech.linkdcs.equipment.model.EquipAlarmParam;
import com.wisdytech.linkdcs.equipment.service.IEquipmentAlarmService;
import com.wisdytech.linkdcs.system.model.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service("equipmentAlarmService")
@Transactional
public class EquipmentAlarmServiceImpl extends BaseService<IEqEquipAlarmParamDao, EquipAlarmParam> implements IEquipmentAlarmService {

    @Resource
    private IEqEquipAlarmParamDao alarmParamDao;

    @Resource
    private IEqAlarmRecordDao alarmRecordDao;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private static final String UNDEAL_ALARM_RECORDS = "undealAlarmRecords";


    @Override
    public PageInfo<EquipAlarmParam> listDefinitions(Filter filter, String eqCode, String eqName) {


        //分页查询告警参数
        List<EquipAlarmParam> params =
                super.beforeList(IEqEquipAlarmParamDao.class, filter).selectAlarmParam(eqCode, eqName);

        PageInfo<EquipAlarmParam> pageInfo = new PageInfo<>(params);

        return pageInfo;
    }

    @Override
    public StandardResult add(EquipAlarmParam param) {
        EntityWrapper<EquipAlarmParam> wrapper = new EntityWrapper<>();
        wrapper.eq("EQUIP_CODE", param.getEquipCode());
        wrapper.eq("PARAM_ID", param.getParamId());
        wrapper.eq("DEL_FLAG", CommonConstants.DEL_FLAG);
        Integer existNum =
                alarmParamDao.selectCount(wrapper);
        if (existNum > 0) {
            return StandardResult.getFailResult("预警定义已存在");
        }
        param.setPkId(BaseUtil.getUUID());
        param.setCreateDate(new Date());
        param.setDelFlag(CommonConstants.DEL_FLAG);
        int num = alarmParamDao.insert(param);
        if (num > 0) {
            //推送告警
            this.sentAlarmToDCS(
                    param.getEquipCode(), param.getParamId(), param.getPkId(), param.getMinimaValue(), param.getMaximaValue());

            return StandardResult.getSuccessResult();
        }

        return StandardResult.getFailResult();
    }

    @Override
    public StandardResult update(EquipAlarmParam param) {
        EntityWrapper<EquipAlarmParam> wrapper = new EntityWrapper<>();

        wrapper.eq("EQUIP_CODE", param.getEquipCode());
        wrapper.eq("PARAM_ID", param.getParamId());
        wrapper.eq("DEL_FLAG", CommonConstants.DEL_FLAG);
        wrapper.ne("pk_id", param.getPkId());
        Integer existNum =
                alarmParamDao.selectCount(wrapper);
        if (existNum > 0) {
            return StandardResult.getFailResult("预警定义已存在");
        }
        EntityWrapper<EquipAlarmParam> ew = new EntityWrapper<>();
        int num = alarmParamDao.update(param, ew.eq("pk_id", param.getPkId()));
        if (num > 0) {
            //推送设备告警
            EquipAlarmParam sendParm = alarmParamDao.selectById(param.getPkId());
            this.sentAlarmToDCS(
                    sendParm.getEquipCode(), sendParm.getParamId()
                    , sendParm.getPkId(), sendParm.getMinimaValue(), sendParm.getMaximaValue());

            return StandardResult.getSuccessResult();
        }


        return StandardResult.getFailResult();
    }

    @Override
    public StandardResult update(List<EquipAlarmParam> params) {
        for (EquipAlarmParam param : params) {
            StandardResult result = this.update(param);
            //删除失败
            if (!result.getResult()) {
                return result;
            }
        }
        return StandardResult.getSuccessResult();
    }

    /**
     * 处理预警记录
     * @param alarmRecord
     */
    @Override
    public void dealAlarmRecord(AlarmRecord alarmRecord, SysUser operator) {
        if (alarmRecord == null||StringUtils.isBlank(alarmRecord.getPkId())) {
            throw new ServiceException("参数错误");
        }
        if (operator == null) {
            throw new ServiceException("操作人不能为空");
        }
        alarmRecord.setStatus(1);
        //alarmRecord.setEndTime(new Date());
        alarmRecord.setProcessTime(new Date());
        alarmRecordDao.updateById(alarmRecord);
        // 除去redis的记录
        String alarmParamId = Optional.ofNullable(alarmRecordDao.selectById(alarmRecord.getPkId()))
                .map(AlarmRecord::getAlarmParamId)
                .orElse("");
        //stringRedisTemplate.opsForHash().delete(UNDEAL_ALARM_RECORDS,alarmParamId);
    }

    @Override
    public StandardResult delete(List<EquipAlarmParam> params) {
        for (EquipAlarmParam param : params) {
            //查找设备信息
            EquipAlarmParam alarmParam = alarmParamDao.selectById(param.getPkId());
            this.delAlarmToDCS(alarmParam.getEquipCode(), alarmParam.getParamId());
            alarmParamDao.updateById(param);

        }
        return StandardResult.getSuccessResult();
    }

    @Override
    public PageInfo<AlarmRecord> listAlarmRecord(Filter filter, String eqCode, String startTime, String endTime) {

        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isNotBlank(eqCode)) {
            params.put("eqCode", eqCode);
        }
        if (StringUtils.isNotBlank(startTime)) {
            params.put("startTime", startTime);
        }
        if (StringUtils.isNotBlank(endTime)) {
            params.put("endTime", endTime);
        }

        List<AlarmRecord> lists = super.beforeList(IEqAlarmRecordDao.class, filter).listAlarmRecords(params);
        return new PageInfo<>(lists);
    }

    @Override
    public StandardResult update(AlarmRecord record) {

        record.setEndTime(new Date());
        Integer result = alarmRecordDao.updateById(record);
        if (result > 0) {
            return StandardResult.getSuccessResult();
        }
        return StandardResult.getFailResult();
    }

    /**
     * <p>Description: 推送告警参数</p>
     *
     * @param equipCode
     * @param paramId
     * @param startValue
     * @param endValue
     */
    private void sentAlarmToDCS(String equipCode, String paramId, String alarmId, double startValue, double endValue) {

        ParamAlarmDefinition definitionDto = new ParamAlarmDefinition();
        definitionDto.setPkId(alarmId);
        definitionDto.setStartKey(startValue);
        definitionDto.setEndKey(endValue);

        stringRedisTemplate.opsForHash().put(
                CommonConstants.ALRAM_EQUIP_START + equipCode, paramId, JSON.toJSONString(definitionDto));


    }

    /**
     * <p>Description: 删除告警参数</p>
     *
     * @param eqCode
     * @param paramId
     */
    private void delAlarmToDCS(String eqCode, String paramId) {
        //删除告警参数
        stringRedisTemplate.opsForHash().delete(CommonConstants.ALRAM_EQUIP_START + eqCode, paramId);
    }


}
